import axios from 'axios';
import {ElMessageBox, ElNotification} from 'element-plus';
import sysConfig from "@/config";
import tool from '@/utils/tool';
import router from '@/router';

axios.defaults.baseURL = ''

axios.defaults.timeout = sysConfig.TIMEOUT

// HTTP request 拦截器
axios.interceptors.request.use((config) => {
	let token = tool.cookie.get("TOKEN");
	if (token) {
		config.headers[sysConfig.TOKEN_NAME] = sysConfig.TOKEN_PREFIX + token
		let ttl = tool.cookie.get("TOKEN_TTL")
		tool.cookie.set("TOKEN", token, {
			expires: ttl ? ttl : 0
		})
	}
	if (!sysConfig.REQUEST_CACHE && config.method == 'get') {
		config.params = config.params || {};
		config.params['_'] = new Date().getTime();
	}
	Object.assign(config.headers, sysConfig.HEADERS)
	return config;
}, (error) => {
	return Promise.reject(error);
});

// HTTP response 拦截器
axios.interceptors.response.use((response) => {

	// 特殊状态码验证
	switch (response.data.status) {
		case 200:
			return response
		case 401:
			tool.cookie.remove("TOKEN")
			tool.data.remove("USER_INFO")
			tool.data.remove("AUTO_LOGIN")
			tool.data.remove("MENU")
			tool.data.remove("PERMISSIONS")
			tool.data.remove("grid")
			var isPrompted = tool.cookie.get("PROMPTED"); // 解决重复弹出的问题
			if (!isPrompted) {
				tool.cookie.set("PROMPTED", true, {
					expires: 5
				})
				ElMessageBox.confirm('当前用户已被登出（凭证过期）或无权限访问当前资源，请尝试重新登录后再操作。', '无权限访问', {
					type: 'error', closeOnClickModal: false, center: true, confirmButtonText: '重新登录'
				}).then(() => {
					tool.cookie.remove("PROMPTED");
					router.replace({path: '/login'});
				})
			}
			return response
	}

	// 响应级别验证
	switch (response.data.level) {
		case "warn":
			ElNotification.warning({
				title: '异常操作', message: response.data.msg
			});
			break;
		case "error":
			ElNotification.error({
				title: '系统错误', message: response.data.msg
			});
			break;
	}
	return response;
}, (error) => {
	if (error.response) {
		switch (error.response.status) {
			case 404:
				ElNotification.error({
					title: '请求错误', message: "Status:404，正在请求不存在的服务器记录！"
				});
				break;
			case 500:
				ElNotification.error({
					title: '系统错误', message: error.response.data.message || "Status:500，服务器发生错误！"
				});
				break;
			case 401:
				tool.cookie.remove("TOKEN")
				tool.data.remove("USER_INFO")
				tool.data.remove("AUTO_LOGIN")
				tool.data.remove("MENU")
				tool.data.remove("PERMISSIONS")
				tool.data.remove("grid")
				ElMessageBox.confirm('当前用户已被登出或无权限访问当前资源，请尝试重新登录后再操作。', '无权限访问', {
					type: 'error', closeOnClickModal: false, center: true, confirmButtonText: '重新登录'
				}).then(() => {
					router.replace({path: '/login'});
				})
				break;
			default:
				ElNotification.error({
					title: '请求错误', message: error.message || `Status:${error.response.status}，未知错误！`
				});
		}
	}
	// return Promise.reject(error.response);
	return error.response
});

var http = {

	/** get 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} params
	 * @param  {参数} config
	 */
	get_download: function (url, params = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'get', url: url, params: params, ...config
			}).then((response) => {
				// resolve(response.data);
				const {data, headers} = response
				const fileName = headers['content-disposition'].replace(/\w+;filename=(.*)/, '$1')
				const blob = new Blob([data], {type: headers['content-type']})
				let dom = document.createElement('a')
				let url = window.URL.createObjectURL(blob)
				dom.href = url
				dom.download = decodeURI(fileName)
				dom.style.display = 'none'
				document.body.appendChild(dom)
				dom.click()
				dom.parentNode.removeChild(dom)
				window.URL.revokeObjectURL(url)
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** get 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} params
	 * @param  {参数} config
	 */
	get: function (url, params = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'get', url: url, params: params, ...config
			}).then((response) => {
				resolve(response.data);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** post 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} data
	 * @param  {参数} config
	 */
	post: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'post', url: url, data: data, ...config
			}).then((response) => {
				resolve(response.data);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** put 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} data
	 * @param  {参数} config
	 */
	put: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'put', url: url, data: data, ...config
			}).then((response) => {
				resolve(response.data);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** patch 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} data
	 * @param  {参数} config
	 */
	patch: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'patch', url: url, data: data, ...config
			}).then((response) => {
				resolve(response.data);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** delete 请求
	 * @param  {接口地址} url
	 * @param  {请求参数} data
	 * @param  {参数} config
	 */
	delete: function (url, params = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'delete', url: url, params: params, ...config
			}).then((response) => {
				resolve(response.data);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** jsonp 请求
	 * @param  {接口地址} url
	 * @param  {JSONP回调函数名称} name
	 */
	jsonp: function (url, name = 'jsonp') {
		return new Promise((resolve) => {
			var script = document.createElement('script')
			var _id = `jsonp${Math.ceil(Math.random() * 1000000)}`
			script.id = _id
			script.type = 'text/javascript'
			script.src = url
			window[name] = (response) => {
				resolve(response)
				document.getElementsByTagName('head')[0].removeChild(script)
				try {
					delete window[name];
				} catch (e) {
					window[name] = undefined;
				}
			}
			document.getElementsByTagName('head')[0].appendChild(script)
		})
	}
}

export default http;
